package schoolmath.web.components.content;

import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.tapestry5.annotations.InjectComponent;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.corelib.components.Form;
import org.apache.tapestry5.corelib.components.Zone;
import org.apache.tapestry5.hibernate.annotations.CommitAfter;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.hibernate.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import schoolmath.web.entities.Role;
import schoolmath.web.services.valueEncoders.RoleEncoder;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@RequiresRoles("Администратор")
public class ManageRolesContent {

	private static Logger logger = LoggerFactory.getLogger(ManageRolesContent.class);
	private List<Role> roles;
	private Role role;
	@Inject
	private Session session;
	@InjectComponent
	private Form rolesEdit;
	@InjectComponent
	private Zone rolesEditZone;
	private boolean inFormSubmission;
	private List<Role> rolesSubmitted;
	private boolean editing;
	@InjectComponent
	private Zone rowZone;
	@Property
	@Inject
	private RoleEncoder roleEncoder;

	public boolean getCreating() {
		return this.role.getId() == null;
	}

	public boolean getChanging() {
		return editing || this.role.getId() == null;
	}

	public String getChangingId() {
		if (editing) {
			return role.getId().toString();
		} else {
			return "";
		}
	}

	public void onActivate() {
		inFormSubmission = false;
	}

	@SuppressWarnings("unchecked")
	public List<Role> getRoles() {
		if (roles == null) {
			roles = session.createCriteria(Role.class)
					.addOrder(org.hibernate.criterion.Order.asc("id")).list();
		}
		return this.roles;
	}

	public Role getRole() {
		return this.role;
	}

	public void setRole(Role role) {
		this.role = role;

		if (inFormSubmission) {
			rolesSubmitted.add(role);
		}
	}

	@CommitAfter
	private void save() {
		for (Role role : rolesSubmitted) {
			session.update(role);
		}
	}

	public void onPrepareForSubmit() {
		inFormSubmission = true;
		rolesSubmitted = new ArrayList<>();
	}

	public void onValidateFromRolesEdit() {
		Set<String> names = new HashSet<>();
		for (Role role : rolesSubmitted) {
			if (names.contains(role.getName())) {
				rolesEdit.recordError("Имеются повторяющиеся роли");
				return;
			}
			names.add(role.getName());
		}
	}

	public Object onSuccess() {
		save();
		roles = null;
		return rolesEditZone.getBody();
	}

	public Object onFailure() {
		roles = new ArrayList<>(rolesSubmitted);
		return rolesEditZone.getBody();
	}

	public Object onRefresh() {
		rolesEdit.clearErrors();
		roles = null;
		return rolesEditZone.getBody();
	}

	public Object onEdit(Role role) {
		this.role = role;
		editing = true;
		return rowZone.getBody();
	}

	public Object onCancel(Role role) {
		this.role = role;
		return rowZone.getBody();
	}

	public Object onRefreshPage() {
		return this;
	}

}
